package com.kehutong.charge.service.impl;


import com.kehutong.charge.dao.ChargeBillHouseDao;
import com.kehutong.charge.dto.ChargeBillItemDTO;
import com.kehutong.charge.dto.MeterStatistDTO;
import com.kehutong.charge.entity.*;
import com.kehutong.charge.service.ChargeBillHouseService;
import com.kehutong.charge.service.CommonService;
import com.kehutong.charge.util.CommonClient;
import com.kehutong.charge.util.CommonUtil;
import com.kehutong.charge.util.enums.ChargeBillStatusEnum;
import com.kehutong.charge.util.enums.ChargeLogEnum;
import com.kehutong.charge.vo.ChargeBillHouseExcelVO;
import com.kehutong.common.Java8TimeUtils;
import com.kehutong.common.errcode.Assert;
import com.kehutong.common.errcode.Result;
import com.kehutong.common.excel.tool.ExcelTool;
import com.kehutong.common.util.BigDecimalUtils;
import com.kehutong.common.util.ListUtils;
import com.kehutong.common.util.Token;
import org.coraframework.bean.Beans;
import org.coraframework.converter.util.StringUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.Condition;
import org.coraframework.orm.jdbc.execute.PageCondition;
import org.coraframework.orm.jdbc.execute.QueryCondition;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;
import org.coraframework.util.time.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: kht
 * @description: ChargeBillHouseServiceImpl
 * @author: joneron
 * @create: 2021/7/5
 **/
public class ChargeBillHouseServiceImpl implements ChargeBillHouseService {

    private static final Logger logger = LoggerFactory.getLogger(ChargeBillHouseServiceImpl.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    CommonClient commonClient;
    @Inject
    CommonService commonService;
    @Inject
    ChargeBillHouseDao chargeBillHouseDao;
    @Inject
    ExcelTool excelTool;


    @Override
    public Page<ChargeBillHouse> findPage(JSONObject jsonObject) {
        FindPage<ChargeBillHouse> find = jdbcSession.findPage(ChargeBillHouse.class);
        find.eq("deleted", false);
        find.eq(jsonObject, "communityNo");
        find.eq(jsonObject, "billYearMonth");
        find.eq(jsonObject, "billStatus");
        find.eq(jsonObject, "chargeStatus");
        find.like(jsonObject, "houseBillNo");
        //添加选中导出条件
        JSONArray exportIdList = jsonObject.getJSONArray("exportIdList");
        if(!Objects.isEmpty(exportIdList)){
            find.in("houseBillNo",exportIdList);
        }
        find.order("createTime", "desc");

        return find.page(jsonObject).exe();
    }

    @Override
    public void pageHouseExport(HttpServletRequest req, HttpServletResponse resp, JSONObject jsonObject) {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);

        List<ChargeBillHouse> list = findPage(jsonObject).getList();
        Assert.notEmpty(list,"没有找到该小区的账单数据.");
        List<ChargeBillHouseExcelVO> billList = ListUtils.copyList(list, ChargeBillHouseExcelVO::new);
        excelTool.excelDownload(req, resp, billList, "常规账单导出");
    }

    @Override
    public List<ChargeBillHouse> findList(JSONObject jsonObject) {
        FindArray findArray = jdbcSession.findArray(ChargeBillHouse.class)
                .eq("deleted", false)
                .eq(jsonObject, "houseNo")
                //.noEq("billStatus",ChargeBillStatusEnum.BILL_PAID_CLOSE)
                .eq(jsonObject, "userNo");

        if ("1".equals(jsonObject.get("noCloseAndUnPaid"))) {
            findArray.markBegin();
            findArray.noEq("billStatus", ChargeBillStatusEnum.BILL_PAID_CLOSE.getId());
            findArray.or();
            findArray.noEq("chargeStatus", ChargeBillStatusEnum.BILL_UN_PAID.getId());
            findArray.markEnd();
        }

        String year = jsonObject.getString("billYearMonth");
        if (Objects.nonNull(year)) {
            findArray.like("billYearMonth",year);
        }
        findArray.order("billYearMonth","desc");

        return findArray.exe();
    }

    @Override
    public Object save(ChargeBillHouse bill) throws Exception {

        ChargeBillHouse old = jdbcSession.findOne(ChargeBillHouse.class)
                .eq("houseNo", bill.getHouseNo())
                .eq("billYearMonth", bill.getBillYearMonth())
                .noEq("billStatus",ChargeBillStatusEnum.BILL_PAID_CLOSE).exe();
        if (null == old) {
            return Result.error(2021, "该房屋没有生成账单，不能重新生成！");
        }

        ChargeBillHouse billHouse = Pool.newInstance(ChargeBillHouse.class);
        Beans.from(old).to(billHouse).exclude("id").igornNull().copy();

        //2、先判断类目账单是否有缴费状态
        List<ChargeBillItems> billItems = jdbcSession.findArray(ChargeBillItems.class)
                .eq("houseBillNo", billHouse.getHouseBillNo())
                .eq("billYearMonth", billHouse.getBillYearMonth())
                .noEq("billStatus", ChargeBillStatusEnum.BILL_UN_PAID)
                .noEq("billStatus", ChargeBillStatusEnum.BILL_PAID_CLOSE).exe();
        //3、有缴费状态则不能重新生成账单
        if (null != billItems && billItems.size() > 0) {
            return Result.error(2021, "该房屋已经有缴费，不能重新生成账单！");
        }

        //先作废
        old.setBillStatus(ChargeBillStatusEnum.BILL_PAID_CLOSE);
        jdbcSession.updateById(old);

        /** 编号，模块，功能，账单状态，状态，说明，操作人 */
        commonService.insetLogger(old.getHouseBillNo(),
                ChargeLogEnum.LOG_CHARGE_BILL_COM.getDesc(),
                "房屋作废操作",
                ChargeBillStatusEnum.BILL_PAID_CLOSE.getDesc(),
                ChargeBillStatusEnum.BILL_UN_PAID.getDesc(), "操作成功！", bill.getCreateName());

        //4、所有类目单项作废
        for (int i = 0; i < billItems.size(); i++) {
            ChargeBillItems items = billItems.get(i);
            items.setBillStatus(ChargeBillStatusEnum.BILL_PAID_CLOSE);
            items.setUpdateTime(TimeUtil.timestamp());
            items.setUpdateName(bill.getCreateName());
            jdbcSession.updateById(items);
        }

        billHouse.setUpdateTime(TimeUtil.timestamp());
        billHouse.setUpdateName(bill.getCreateName());
        jdbcSession.updateById(billHouse);

        String houseNo = billHouse.getHouseNo();
        String yearMonth = billHouse.getBillYearMonth();

        //1、根据房屋id查询费用配置绑定项,可能配置多次
        ChargeHouseConfig houseConfig = jdbcSession.findOne(ChargeHouseConfig.class)
                .eq("houseNo", houseNo).exe();

        List<ChargeHouseSet> houseSetList = jdbcSession.findArray(ChargeHouseSet.class)
                .eq("chargeHouseNo", houseConfig.getId()).exe();

        if (null == houseSetList || 0 == houseSetList.size()) {
            logger.warn("房屋：{},没有设置收费项目！", houseNo);
            return Result.error(2021, "该房屋没有设置收费项目！");
        }

        //创建房屋账单
        billHouse.setHouseBillNo(CommonUtil.generateRandom("FW"));
        billHouse.setChargeName(houseConfig.getChargeName());
        billHouse.setResidentsType(houseConfig.getReType());
        billHouse.setBillYearMonth(yearMonth);
        BigDecimal amountHouse = BigDecimal.ZERO;

        for (int i = 0; i < houseSetList.size(); i++) {

            //3、根据费用配置项id查询具体配置信息，并计算费用
            ChargeHouseSet chs = houseSetList.get(i);

            //4、查询费用配置参数
            ChargeProjectConfig pconfig = jdbcSession.findById(ChargeProjectConfig.class, chs.getProjectFeeNo());

            //5、查询仪表类型
            ChargeTypeConfig typeConfig = jdbcSession.findById(ChargeTypeConfig.class, pconfig.getFeeTypeNo());

            //6、根据房屋和类型、月份、周期、查询抄表使用量(有多次抄表的情况)
            List<MeterReading> meterReading = jdbcSession.findArray(MeterReading.class)
                    .eq("houseNo", chs.getHouseNo())
                    .eq("meterTypeNo", typeConfig.getMeterTypeNo())
                    .like("endTime", billHouse.getBillYearMonth())
                    .exe();

            if (null == meterReading || meterReading.size() == 0) {
                logger.warn("房间：{},在{}没有抄表数据！", chs.getHouseNo(), billHouse.getBillYearMonth());
                continue;
            }

            for (int j = 0; j < meterReading.size(); j++) {

                MeterReading reading = meterReading.get(j);
                ChargeBillItems items = Pool.newInstance(ChargeBillItems.class);
                String billNO = CommonUtil.generateRandom("FX");
                items.setItemBillNo(billNO);
                items.setBillStatus(ChargeBillStatusEnum.BILL_UN_PAID);
                //7、计算单个类型的总费用
                BigDecimal amount = commonService.calcFeeCommon(pconfig, reading.getTimeUseNumber(), billNO);
                amount = amount.setScale(2, BigDecimal.ROUND_UP); //保存两位小数,只入不舍
                amountHouse = amountHouse.add(amount);
                items.setBillAmount(amount);
                items.setFeeTypeName(typeConfig.getFeeTypeName());
                items.setFeeTypeNo(typeConfig.getId());
                items.setChargeName(houseConfig.getChargeName());
                items.setUserNo(houseConfig.getOwnerNo());
                items.setResidentsType(houseConfig.getReType());
                items.setCreateName(billHouse.getCreateName());
                items.setBillCycleStart(billHouse.getBillCycleStart());
                items.setBillCycleEnd(billHouse.getBillCycleEnd());
                items.setBillDate(billHouse.getBillDate());
                items.setChargeDate(billHouse.getChargeDate());
                items.setDepartmentNo(billHouse.getDepartmentNo());
                items.setDepartmentName(billHouse.getDepartmentName());
                items.setDepartmentNos(billHouse.getDepartmentNos());
                items.setCommunityNo(reading.getCommunityNo());
                items.setCommunityName(reading.getCommunityName());
                items.setCommunityBillNo(billHouse.getCommunityBillNo());
                items.setHouseNo(chs.getHouseNo());
                items.setHouseBillNo(billHouse.getHouseBillNo());
                items.setMeterTypeNo(reading.getMeterTypeNo());
                items.setMeterTypeName(reading.getMeterTypeName());
                items.setMeterClassifyName(reading.getMeterClassifyName());
                items.setMeterClassifyNo(reading.getMeterClassifyNo());
                items.setBillYearMonth(billHouse.getBillYearMonth());
                items.setUsageNumber(reading.getTimeUseNumber());
                items.setBillAddress(reading.getMeterAddress());
                items.setPenaltyDays(Java8TimeUtils.subDate(billHouse.getPenaltyDate()));
                items.setPenaltyAmount(new BigDecimal(0));
                items.setPenaltyDate(billHouse.getPenaltyDate());
                items.setCalcUnit(reading.getCalcUnit());
                items.setPayableAmount(amount);
                items.setPrice(pconfig.getPrice());
                items.setLastTimeNumber(reading.getLastTimeNumber());
                items.setTimeNumber(reading.getTimeNumber());
                items.setStartTime(reading.getStartTime());
                items.setEndTime(reading.getEndTime());

                //8、记录费用项
                jdbcSession.insert(items);

                /** 编号，模块，功能，账单状态，状态，说明，操作人 */
                commonService.insetLogger(items.getItemBillNo(),
                        ChargeLogEnum.LOG_CHARGE_BILL_CATE.getDesc(),
                        "生成类目账单",
                        ChargeBillStatusEnum.BILL_WAIT_PAID.getDesc(),
                        ChargeBillStatusEnum.BILL_UN_PAID.getDesc(), "操作成功！", bill.getCreateName());
            }

        }

        billHouse.setBillAmount(amountHouse);
        billHouse.setBillAmountUnPaid(amountHouse);
        billHouse.setUpdateTime(TimeUtil.timestamp());
        billHouse.setUpdateName(bill.getCreateName());

        //9、添加房屋账单
        return jdbcSession.insert(billHouse);
    }

    @Override
    public Object update(ChargeBillHouse chargeBillHouse) throws Exception {
        return jdbcSession.updateById(chargeBillHouse);
    }

    @Override
    public Object deleteById(String id) {
        return null;
    }

    @Override
    public Object findBillHouseList(JSONObject jsonObject) {

        List<ChargeBillItemDTO> billItemDTOS = new LinkedList<>();

        ChargeBillItemDTO itemDTO = null;
        //1、根据房屋账单编号查询所有账单列表
        FindArray<ChargeBillItems> billItemsFindArray = jdbcSession.findArray(ChargeBillItems.class)
                .eq(jsonObject, "houseBillNo")
                .eq(jsonObject, "itemBillNo");

        // 查询房屋账单
        /*
        String houseBillNo = jsonObject.getString("houseBillNo");
        if (!Objects.isBlank(houseBillNo)) {
            ChargeBillHouse chargeBillHouse = jdbcSession.findOne(ChargeBillHouse.class).eq("houseBillNo", houseBillNo).exe();
            ChargeBillStatusEnum billStatusEnum = chargeBillHouse.getBillStatus();
            if (billStatusEnum != ChargeBillStatusEnum.BILL_PAID_CLOSE) {
                billItemsFindArray.noEq("billStatus", ChargeBillStatusEnum.BILL_PAID_CLOSE.getId());
            } else {
                billItemsFindArray.eq("billStatus", billStatusEnum.getId());
            }
        }*/
        List<ChargeBillItems> billItems = billItemsFindArray.exe();

        /**
        Set<String> meterTypeNos = new HashSet<>();
        for (int i = 0; i < billItems.size(); i++) {
            meterTypeNos.add(billItems.get(i).getMeterTypeNo());
        }

        //List<MeterTypeConfig> configs = jdbcSession.findArray(MeterTypeConfig.class).in("id", meterTypeNos).exe();

        //Map<String, String> configMap = configs.stream().collect(Collectors.toMap(MeterTypeConfig::getId, MeterTypeConfig::getTypeName));
        */
        for (int i = 0; i < billItems.size(); i++) {
            ChargeBillItems items = billItems.get(i);
            itemDTO = new ChargeBillItemDTO();
            itemDTO.setFeeTypeName(items.getFeeTypeName());
            itemDTO.setFeeTypeNo(items.getMeterTypeNo());
            itemDTO.setItemBillNo(items.getItemBillNo());
            itemDTO.setHouseBillNo(items.getHouseBillNo());
            itemDTO.setCalcUnit(items.getCalcUnit());
            itemDTO.setUsageNumber(items.getUsageNumber());
            itemDTO.setBillAmount(items.getBillAmount());
            itemDTO.setBillStatus(items.getBillStatus());
            itemDTO.setPayableAmount(items.getPayableAmount());
            itemDTO.setPaymentAmount(items.getPaymentAmount());
            billItemDTOS.add(itemDTO);
        }

        //2、临时费项
        /**
        List<ChargeBillInterim> interims = jdbcSession.findArray(ChargeBillInterim.class)
                .eq(jsonObject, "houseBillNo")
                .eq(jsonObject,"itemBillNo")
                .eq("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID).exe();

        for (int i = 0; i < interims.size(); i++) {
            ChargeBillInterim items = interims.get(i);
            itemDTO = new ChargeBillItemDTO();
            itemDTO.setBillItemName(items.getFeeTypeName());
            itemDTO.setItemBillNo(items.getInterimBillNo());
            itemDTO.setHouseBillNo(items.getHouseBillNo());
            itemDTO.setBillAmount(items.getBillAmount());
            billItemDTOS.add(itemDTO);
        }

        //3、违约金费项
        List<ChargeBillItemDTO> itemDTOList = findPenalty(jsonObject);
        for (int i = 0; i < itemDTOList.size(); i++) {
            ChargeBillItemDTO itemDTO1 = itemDTOList.get(i);
            if(null != itemDTO1){
                itemDTO1.setBillStatus(ChargeBillStatusEnum.BILL_WAIT_PAID);
                billItemDTOS.add(itemDTO1);
            }
        }*/

        return billItemDTOS;
    }

    /**
     * 查询违约金
     */
    @Override
    public List<ChargeBillItemDTO> findPenalty(JSONObject jsonObject) {
        QueryCondition query = Condition.createQuery(false);

        query.eq("deleted", false);
        query.eq(jsonObject,"houseBillNo");
        query.eq(jsonObject,"itemBillNo");
        query.eq(jsonObject,"houseNo");
        query.eq("billStatus",ChargeBillStatusEnum.BILL_WAIT_PAID);
        query.groupBy("houseNo");
        query.groupBy("billYearMonth");

        return chargeBillHouseDao.housePenalty(query);
    }


    /**
     * 账单详情（根据住户号统计该用户所有月份的代缴费账单）
     *
     * @param jsonObject
     * @return
     */
    @Override
    public Object houseAllUnpaidMonth(JSONObject jsonObject) {
        String billYearMonth = jsonObject.getString("billYearMonth");
        String feeTypeName = jsonObject.getString("feeTypeName");
        String houseNo = jsonObject.getString("houseNo");
        if (Objects.isEmpty(houseNo)) {
            return Result.error(0, "房屋编号不能为空.");
        }
        QueryCondition query = Condition.createQuery(false);
        if (!Objects.isEmpty(billYearMonth)) {
            query.eq("billYearMonth", billYearMonth);
        }
        if (!Objects.isEmpty(feeTypeName)) {
            query.eq("feeTypeName", feeTypeName);
        }
        query.eq("deleted", false);
        query.eq("houseNo", houseNo);
        query.eq("billStatus", "1");
        query.groupBy("billYearMonth");
        query.order("billYearMonth", "desc");

        List<Map<String, Object>> maps = chargeBillHouseDao.houseMonthBill(query);
        BigDecimal unpaidTotalAmount = BigDecimal.ZERO;
        for (Map<String, Object> map : maps) {
            BigDecimal monthUnpaidTotalAmount = (BigDecimal) map.get("payableAmountTotal");
            unpaidTotalAmount = BigDecimalUtils.add(monthUnpaidTotalAmount, unpaidTotalAmount);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("unpaidTotalAmount", unpaidTotalAmount);
        result.put("list", maps);
        return result;
    }


    /**
     * 账单详情（根据住户号和年份统计该用户当年账单列表）
     *
     * @param jsonObject
     * @return
     */
    @Override
    public Object houseYear(JSONObject jsonObject) {
        String houseNo = jsonObject.getString("houseNo");
        if (Objects.isEmpty(houseNo)) {
            return Result.error(0, "房屋编号不能为空.");
        }
        String year = jsonObject.getString("year");
        if (Objects.isEmpty(year)) {
            return Result.error(0, "要查的年份(yyyy)不能为空.");
        }
        QueryCondition query = Condition.createQuery(false);
        query.eq("deleted", false);
        query.eq("houseNo", houseNo);
        query.eq("DATE_FORMAT(chargeDate, '%Y')", year);
        query.groupBy("billYearMonth");
        query.groupBy("billStatus");
        query.order("billYearMonth", "desc");
        List<Map<String, Object>> maps = chargeBillHouseDao.houseMonthBill(query);

        Set<Object> billYearMonthSet = maps.stream().map(m -> m.get("billYearMonth")).collect(Collectors.toSet());

        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> yearMonthMap;
        BigDecimal unpaidTotalAmount = BigDecimal.ZERO;
        for (Object yearMonth : billYearMonthSet) {
            Map<String, Object> billYearMonth = maps.stream().filter(m -> yearMonth.equals(m.get("billYearMonth"))).findFirst().orElse(null);
            if (Objects.isEmpty(billYearMonth)) {
                continue;
            }

            long totalNum = 0;
            Map<String, Object> unpaidAmountMap = maps.stream().filter(m -> ChargeBillStatusEnum.BILL_UN_PAID.getId()
                    .equals(m.get("billStatus")) && yearMonth.equals(m.get("billYearMonth"))).findFirst().orElse(null);
            BigDecimal unpaidAmount = BigDecimal.ZERO;
            if (!Objects.isEmpty(unpaidAmountMap)) {
                unpaidAmount = (BigDecimal) unpaidAmountMap.get("payableAmountTotal");
                totalNum += (long) unpaidAmountMap.get("totalNum");
            }
            Map<String, Object> paidAmountMap = maps.stream().filter(m -> ChargeBillStatusEnum.BILL_PAID.getId()
                    .equals(m.get("billStatus")) && yearMonth.equals(m.get("billYearMonth"))).findFirst().orElse(null);
            BigDecimal paidAmount = BigDecimal.ZERO;
            if (!Objects.isEmpty(paidAmountMap)) {
                paidAmount = (BigDecimal) paidAmountMap.get("payableAmountTotal");
                totalNum += (long) paidAmountMap.get("totalNum");
            }
            unpaidTotalAmount = BigDecimalUtils.add(unpaidAmount, unpaidTotalAmount);

            yearMonthMap = new HashMap<>();
            yearMonthMap.put("billYearMonth", yearMonth);
            yearMonthMap.put("chargeDate", billYearMonth.get("chargeDate"));
            yearMonthMap.put("houseNo", billYearMonth.get("houseNo"));
            yearMonthMap.put("billAddress", billYearMonth.get("billAddress"));
            yearMonthMap.put("chargeName", billYearMonth.get("chargeName"));
            yearMonthMap.put("billCycleStart", billYearMonth.get("billCycleStart"));
            yearMonthMap.put("billCycleEnd", billYearMonth.get("billCycleEnd"));
            yearMonthMap.put("billDate", billYearMonth.get("billDate"));
            yearMonthMap.put("totalNum", totalNum);
            yearMonthMap.put("unpaidAmount", unpaidAmount);
            yearMonthMap.put("paidAmount", paidAmount);
            yearMonthMap.put("billTotalAmount", BigDecimalUtils.add(unpaidAmount, paidAmount));
            list.add(yearMonthMap);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("unpaidTotalAmount", unpaidTotalAmount);
        result.put("list", list);
        return result;
    }


    @Override
    public Object resetHouseBill(JSONObject jsonObject, Token token) throws Exception {


        return null;
    }


    @Override
    public Object cancelHouseBill(JSONObject jsonObject, Token token) {

        JSONArray jsonArray = jsonObject.getJSONArray("houseBillNos");

        for (int i = 0; i < jsonArray.size(); i++) {

            String billNo = jsonArray.get(i).toString();
            //1、查询对应的小区
            ChargeBillHouse community = jdbcSession.findOne(ChargeBillHouse.class).eq("houseBillNo", billNo).exe();

            //2、判断小区下面账单是否有缴费，有缴费则操作失败
            if (ChargeBillStatusEnum.BILL_WAIT_PAID.equals(community.getBillStatus())) {

                community.setBillStatus(ChargeBillStatusEnum.BILL_PAID_CLOSE);
                community.setUpdateName(token.getUsername());
                community.setUpdateTime(TimeUtil.timestamp());
                //3、房屋数据作废
                jdbcSession.updateById(community);

                //4、类目数据作废
                List<ChargeBillItems> billItems = jdbcSession.findArray(ChargeBillItems.class).eq(
                        "houseBillNo", community.getHouseBillNo()).exe();
                for (int j = 0; j < billItems.size(); j++) {
                    ChargeBillItems items = billItems.get(j);
                    items.setBillStatus(ChargeBillStatusEnum.BILL_PAID_CLOSE);
                    items.setUpdateName(token.getUsername());
                }
                jdbcSession.updateById(billItems);

                // 更改抄表统计状态
                List<MeterReadStatist> readStatists = jdbcSession.findArray(MeterReadStatist.class)
                        .eq("deleted", false)
                        .eq("houseNo", community.getHouseNo())
                        .like("readYearMonth", community.getBillYearMonth())
                        .exe();
                if (!Objects.isEmpty(readStatists)) {
                    for (MeterReadStatist each : readStatists) {
                        each.setFeeStatus("2");
                    }
                    jdbcSession.updateById(readStatists);
                }

                /** 编号，模块，功能，账单状态，状态，说明，操作人 */
                commonService.insetLogger(billNo,
                        ChargeLogEnum.LOG_CHARGE_BILL_COM.getDesc(),
                        "房屋作废操作",
                        ChargeBillStatusEnum.BILL_PAID_CLOSE.getDesc(),
                        ChargeBillStatusEnum.BILL_UN_PAID.getDesc(), "操作成功！", token.getUsername());
            }


        }

        return Result.success("作废成功");
    }


    /**
     * 账单详情（根据住户号和年月统计该用户账单总金额和未缴、已缴、退款账单）
     *
     * @param jsonObject
     * @return
     */
    @Override
    public Object houseYearMonth(JSONObject jsonObject) {
        String yearMonth = jsonObject.getString("yearMonth");
        if (Objects.isEmpty(yearMonth)) {
            return Result.error(0, "要查的年月(yyyy-MM)不能为空.");
        }
        String houseNo = jsonObject.getString("houseNo");
        if (Objects.isEmpty(houseNo)) {
            return Result.error(0, "房屋编号不能为空.");
        }
        QueryCondition query = Condition.createQuery(false);
        query.eq("deleted", false);
        query.eq("houseNo", houseNo);
        query.eq("billYearMonth", yearMonth);
        query.groupBy("billStatus");
        query.order("billYearMonth", "desc");
        List<Map<String, Object>> maps = chargeBillHouseDao.houseMonthBill(query);
        Map<String, Object> result = new HashMap<>();
        if (Objects.isEmpty(maps)) {
            return result;
        }
        //账单总笔数
        long billCount = 0;
        //获取不同状态的账单统计
        BigDecimal unpaidAmount = BigDecimal.ZERO;
        Map<String, Object> unpaidAmountMap = maps.stream().filter(m -> ChargeBillStatusEnum.BILL_UN_PAID.getId()
                .equals(m.get("billStatus"))).findFirst().orElse(null);
        if (!Objects.isEmpty(unpaidAmountMap)) {
            unpaidAmount = (BigDecimal) unpaidAmountMap.get("payableAmountTotal");
            billCount += (long) unpaidAmountMap.get("totalNum");
        } else {
            //TODO 没有未缴账单，意味着已缴清，需要填充订单流水号
        }
        Map<String, Object> paidAmountMap = maps.stream().filter(m -> ChargeBillStatusEnum.BILL_PAID.getId()
                .equals(m.get("billStatus"))).findFirst().orElse(null);
        BigDecimal paidAmount = BigDecimal.ZERO;
        if (!Objects.isEmpty(paidAmountMap)) {
            paidAmount = (BigDecimal) paidAmountMap.get("payableAmountTotal");
            billCount += (long) paidAmountMap.get("totalNum");
        }
        BigDecimal refundAmount = BigDecimal.ZERO;
        Map<String, Object> refundAmountMap = maps.stream().filter(m -> ChargeBillStatusEnum.BILL_REFUND.getId()
                .equals(m.get("billStatus"))).findFirst().orElse(null);
        if (!Objects.isEmpty(refundAmountMap)) {
            refundAmount = (BigDecimal) refundAmountMap.get("payableAmountTotal");
        }
        //账单总金额
        BigDecimal billTotalAmount = BigDecimalUtils.add(unpaidAmount, paidAmount);

        result.put("unpaidAmount", unpaidAmount);
        result.put("billTotalAmount", billTotalAmount);
        result.put("billCount", billCount);
        result.put("refundAmount", refundAmount);
        result.put("paidAmount", paidAmount);
        result.put("paidAmount", paidAmount);

        Map<String, Object> outerMap = maps.get(0);
        result.put("billYearMonth", outerMap.get("billYearMonth"));
        result.put("billCycleStart", outerMap.get("billCycleStart"));
        result.put("billCycleEnd", outerMap.get("billCycleEnd"));
        result.put("chargeDate", outerMap.get("chargeDate"));
        result.put("houseNo", outerMap.get("houseNo"));
        result.put("chargeName", outerMap.get("chargeName"));
        result.put("billAddress", outerMap.get("billAddress"));
        return result;
    }

    @Override
    public ChargeBillHouse getObj(JSONObject jsonObject) {

        return jdbcSession.findOne(ChargeBillHouse.class)
                .eq(jsonObject, "houseBillNo")
                .noEq("billStatus", ChargeBillStatusEnum.BILL_PAID_CLOSE)
                .exe();
    }



}
